package controller

import (
	"context"
	"sort"
	"strconv"
	"strings"

	"sale-admin/config/mysql"
	"sale-admin/internal/app/grpc/client"
	"sale-admin/internal/app/grpc/protoc/system_admin"
	"sale-admin/internal/app/web/schema"
	"sale-admin/internal/app/web/service"
	"sale-admin/internal/dal"
	"sale-admin/internal/dao"
	"sale-admin/internal/define"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/logx"
	"192.168.1.75/go-pkg/response"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/samber/lo"
)

type Payments struct{}

// AllPayments 所有支付方式
func (s Payments) AllPayments(c *gin.Context) {
	data := []struct {
		ID      string `json:"id"`
		PayName string `json:"pay_name"`
	}{}
	for id, name := range define.PaymentTypeMap {
		data = append(data, struct {
			ID      string `json:"id"`
			PayName string `json:"pay_name"`
		}{
			ID:      id,
			PayName: name,
		})
	}
	// 排序
	sort.Slice(data, func(i, j int) bool {
		iID, _ := strconv.Atoi(data[i].ID)
		jID, _ := strconv.Atoi(data[j].ID)
		return iID < jID
	})
	response.JSON(c, data, nil)
}

// 给商户分配支付方式
func (s Payments) SetMerchantPayment(c *gin.Context) {
	var Params struct {
		PaymentsID string `json:"payments_id"`
		MerchantID string `json:"merchant_id"`
	}
	err := c.ShouldBindJSON(&Params)
	if err != nil {
		response.JSON(c, nil, errorx.New("参数错误！", -1))
		return
	}

	db := mysql.NewDB()
	loginMerchantID := c.GetString("merchant_id")
	count, err := service.PaymentsService{}.SetMerchantPayment(c.Request.Context(), db,
		loginMerchantID, Params.PaymentsID, Params.MerchantID)

	if err == nil {
		response.JSON(c, count, errorx.New("配置成功！", 0))
	}
}

// PaymentRemove 删除支付方式
func (s Payments) PaymentRemove(c *gin.Context) {
	var Params struct {
		PaymentID  string `json:"payment_id"` // 支付类型ID， 1 微信, 2 支付宝...
		DetailID   int    `json:"detail_id"`  // 支付方式ID
		MerchantID string `json:"merchant_id"`
	}
	err := c.ShouldBindJSON(&Params)
	if err != nil {
		response.JSON(c, nil, errorx.New("参数错误！", -1))
		return
	}

	// 判断第三方支付类别ID是否为空
	if Params.PaymentID == "" {
		response.JSON(c, nil, errorx.New("第三方支付类别ID不能为空", -1))
		return
	}
	if Params.DetailID == 0 {
		response.JSON(c, nil, errorx.New("删除ID不能为空", -1))
		return
	}

	merchantID := Params.MerchantID
	if merchantID == "" {
		merchantID = c.GetString("merchant_id")
	}

	// 只有商户自己可以分配支付方式
	if merchantID != "1" && Params.PaymentID != "" {
		count, err := service.PaymentsService{}.PaymentRemove(c.Request.Context(),
			merchantID, Params.PaymentID, Params.DetailID)
		if err == nil && count >= 0 {
			response.JSON(c, count, errorx.New("删除支付配置成功！", 0))
			return
		} else {
			response.JSON(c, count, errorx.New("删除支付配置失败!", -1))
			return
		}
	} else {
		response.JSON(c, nil, errorx.New("只有商户可以删除支付方式", -1))
		return
	}
}

/*
 * 获取支付配置详情
 */
func (s Payments) PaymentDetail(c *gin.Context) {
	var Params struct {
		PaymentID string `json:"payment_id"` // 支付方式ID， 1 微信 2 支付包 3聚合 6大兴支付
		ID        string `json:"id"`         // 商户ID
	}

	err := c.ShouldBindJSON(&Params)
	if err != nil {
		response.JSON(c, nil, errorx.New("参数错误！", -1))
		return
	}
	merchantID := c.GetString("merchant_id")
	db := mysql.NewDB()
	var Res struct {
		WechatPay   []schema.PaymentWechatRsp `json:"wechat_pay"`
		SmallPay    []schema.PaymentSmallRsp  `json:"small_pay"`
		PosPay      []schema.PaymentPosRsp    `json:"pos_pay"`
		Alipay      []schema.PaymentAlipayRsp `json:"alipay"`
		AliMicroPay []schema.PaymentAlipayRsp `json:"ali_micro_pay"`
		AliBarCode  []schema.PaymentAlipayRsp `json:"ali_bar_code"`
		JuhePay     []schema.PaymentJhRsp     `json:"juhe_pay"`
		DaxingPay   []schema.PaymentDxRsp     `json:"dx"`
		StripePay   []schema.PaymentStripeRsp `json:"stripe_pay"`
		Stripe2Pay  []struct {
			ID   int    `json:"id"`
			Name string `json:"name"`
		} `json:"stripe2_pay"`
		WappPay []struct {
			ID   int    `json:"id"`
			Name string `json:"name"`
		} `json:"wapp_pay"`
	}
	// 传了商户的ID 并且ID不是管理员
	if Params.ID != "" && Params.ID != "1" {
		merchantID = Params.ID
	}

	if Params.PaymentID == define.PaymentType_Wechat {
		Res.WechatPay, _ = dao.Payment{}.GetWechatPay(context.Background(), dal.Q, merchantID, 0)
	} else if Params.PaymentID == define.PaymentType_XiaoTianCai {
		Res.SmallPay, _ = dao.Payment{}.GetXiaotiancaiPay(context.Background(), dal.Q, merchantID, 0)
	} else if Params.PaymentID == define.PaymentType_POS {
		Res.PosPay, _ = dao.Payment{}.GetPOSPay(context.Background(), dal.Q, merchantID, 0)
	} else if Params.PaymentID == define.PaymentType_Alipay || Params.PaymentID == define.PaymentType_AliMicro { // 支付宝及支付宝人脸
		Res.Alipay, _ = dao.Payment{}.GetAliPay(context.Background(), dal.Q, merchantID, 0)
	} else if Params.PaymentID == define.PaymentType_JuHe {
		Res.JuhePay, _ = dao.Payment{}.GetJuhePay(context.Background(), dal.Q, merchantID, 0)
	} else if Params.PaymentID == define.PaymentType_DaXing {
		Res.DaxingPay, _ = dao.Payment{}.GetDaxingPay(context.Background(), dal.Q, merchantID, 0)
	} else if Params.PaymentID == define.PaymentType_Stripe {
		Res.StripePay, _ = dao.Payment{}.GetStripePay(context.Background(), dal.Q, merchantID, 0)
	} else if Params.PaymentID == define.PaymentType_Stripe2 {
		MerchantConfig, count, _ := dao.MerchantConfig{}.GetDetail(context.Background(), db, merchantID)
		if count > 0 {
			paymentList := strings.Split(MerchantConfig.PaymentsID, ",")
			if lo.Contains(paymentList, define.PaymentType_Stripe2) {
				Res.Stripe2Pay = append(Res.Stripe2Pay, struct {
					ID   int    `json:"id"`
					Name string `json:"name"`
				}{
					ID:   1,
					Name: "stripe2默认支付",
				})
			}
		}
	} else if Params.PaymentID == define.PaymentType_Wapp {
		MerchantConfig, count, _ := dao.MerchantConfig{}.GetDetail(context.Background(), db, merchantID)
		if count > 0 {
			paymentList := strings.Split(MerchantConfig.PaymentsID, ",")
			if lo.Contains(paymentList, define.PaymentType_Wapp) {
				Res.WappPay = append(Res.WappPay, struct {
					ID   int    `json:"id"`
					Name string `json:"name"`
				}{
					ID:   1,
					Name: "小程序默认支付",
				})
			}
		}
	} else {
		Res.WechatPay, _ = dao.Payment{}.GetWechatPay(context.Background(), dal.Q, merchantID, 0)
		Res.SmallPay, _ = dao.Payment{}.GetXiaotiancaiPay(context.Background(), dal.Q, merchantID, 0)
		Res.PosPay, _ = dao.Payment{}.GetPOSPay(context.Background(), dal.Q, merchantID, 0)
		Res.Alipay, _ = dao.Payment{}.GetAliPay(context.Background(), dal.Q, merchantID, 0)
		Res.JuhePay, _ = dao.Payment{}.GetJuhePay(context.Background(), dal.Q, merchantID, 0)
		Res.DaxingPay, _ = dao.Payment{}.GetDaxingPay(context.Background(), dal.Q, merchantID, 0)
		Res.StripePay, _ = dao.Payment{}.GetStripePay(context.Background(), dal.Q, merchantID, 0)
		MerchantConfig, count, _ := dao.MerchantConfig{}.GetDetail(context.Background(), db, merchantID)
		if count > 0 {
			paymentList := strings.Split(MerchantConfig.PaymentsID, ",")
			// stripe2支付
			if lo.Contains(paymentList, define.PaymentType_Stripe2) {
				Res.Stripe2Pay = append(Res.Stripe2Pay, struct {
					ID   int    `json:"id"`
					Name string `json:"name"`
				}{
					ID:   1,
					Name: "stripe2默认支付",
				})
			}
			// 小程序支付
			if lo.Contains(paymentList, define.PaymentType_Wapp) {
				Res.WappPay = append(Res.WappPay, struct {
					ID   int    `json:"id"`
					Name string `json:"name"`
				}{
					ID:   1,
					Name: "小程序默认支付",
				})
			}
		}
	}
	response.JSON(c, Res, nil)
}

/*
* 为商户设置第三方支付配置信息
* PaymentID 支付方式ID
 */
func (s Payments) SetThirdPay(c *gin.Context) {
	var Params schema.ThirdConfigData
	err := c.ShouldBindBodyWith(&Params, binding.JSON)
	if err != nil {
		response.JSON(c, nil, errorx.New("参数错误！", -1))
		return
	}

	merchantID := Params.MerchantID
	if merchantID == "" {
		merchantID = c.GetString("merchant_id")
	}

	// 只有商户自己可以分配支付方式
	if merchantID != "1" && Params.PaymentID != "" {
		count, err := service.PaymentsService{}.SetThirdPay(c.Request.Context(), merchantID, Params)
		if err == nil && count >= 0 {
			response.JSON(c, count, errorx.New("配置支付方式成功！", 0))
		} else {
			response.JSON(c, count, errorx.New("配置支付方式失败!", -1))
		}
	} else {
		response.JSON(c, nil, errorx.New("只有商户可以配置支付方式", -1))
		return
	}
}

// 证书验证
func (s Payments) CertConfirm(c *gin.Context) {
	var params struct {
		Cert string `json:"cert"`
	}
	c.ShouldBindBodyWith(&params, binding.JSON)
	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		logx.Error(c.Request.Context(), "cert confirm file error", logx.Any("err", clientErr.Error()))
		return
	}

	var req system_admin.ConfirmFileReq
	req.FileUrl = params.Cert
	res, err1 := SystemAdminClient.ConfirmFile(c.Request.Context(), &req)
	if err1 != nil && res.Code != 0 {
		logx.Error(c.Request.Context(), "cert confirm file error", logx.Any("res", res), logx.Any("err", err1.Error()))
		return
	}
}
